
/* -----------------
* brief 
* 1. this is code gen by tools 
* 2. mvc code are driver by the model defined with the same filename,
	 for example:
	 there is a Xmodel struct define in xmodel.go file, after the script run (lego model-mvc module_name xmodel)
     it will auto create the code under the module's path
	 m --> xmodel.go
	 v --> view
	 c --> xmodel_ctrl 
* 3. you should modify this code if it doesn't satisfy your purpose   
*/

package controller

import (
	"encoding/json"
	"encoding/xml"
	"fmt"
	"github.com/chanxuehong/wechat/mch/pay"
	"github.com/chanxuehong/wechat/mch/sandbox"
	paytools "github.com/chanxuehong/wechat/mch/tools"
	"github.com/mjiulee/lego"
	"github.com/valyala/fasthttp"
	"saas_sys_base/common"
	. "saas_sys_base/modules/user/service"
	. "saas_sys_base/modules/wechat/service"
)

type WechatPayApiCtrl struct {
	wxWeappMchPayService WxWeappMchPayService
	userService UserService
	wxUserService WxUserService
}


func init () {
	vc:= new(WechatPayApiCtrl)
	vc.wxWeappMchPayService = *NewWxWeappMchPayService()
	_ctrlList = append(_ctrlList,vc)
}

func (vc*WechatPayApiCtrl)CtrlInfo() string {
	return "WechatPayApiCtrl"
}


func (vc *WechatPayApiCtrl) RoutInit() {


	lego.APIPOST("/api/mod/wechat/pay/closeorder", vc.CloseOrder, true)
	//lego.APIPOST("/api/mod/wechat/pay/downloadbill", vc.OrderQuery, true)
	lego.APIPOST("/api/mod/wechat/pay/micropay", vc.MicroPay, true)
	lego.APIPOST("/api/mod/wechat/pay/orderquery", vc.OrderQuery, true)
	lego.APIPOST("/api/mod/wechat/pay/refund", vc.Refund, true)
	lego.APIPOST("/api/mod/wechat/pay/refundquery", vc.RefundQuery, true)
	lego.APIPOST("/api/mod/wechat/pay/reverse", vc.Reverse, true)
	lego.APIPOST("/api/mod/wechat/pay/unifiedorder", vc.Unifiedorder, true)

	lego.APIPOST("/api/mod/wechat/getsignkey", vc.GetSignKey, true)
}




//Unifiedorder用于小程序支付
func (vc *WechatPayApiCtrl) Unifiedorder(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := "success"

	type Request struct {
		*pay.UnifiedOrderRequest
		PayTo common.PAY_TO
	}

	type Resp struct {
		UnifiedOrderResponse *pay.UnifiedOrderResponse
		PaySignResult *pay.PaySignResult `json:",omitempty"`
	}

	var request Request
	var resp Resp

	for {
		sessionData := common.GetSessionData(&ctxExt)
		who := sessionData.AppTokenWho

		requestByte := ctxExt.PostBody()
		err := json.Unmarshal(requestByte, &request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		if request.PayTo != common.PAY_TO_SYS &&
			request.PayTo != common.PAY_TO_TENANT {
			code = -1
			msg = "PayTo para is wrong"
			break
		}

		wxuser := vc.wxUserService.GetWxUserByUid(who.Uid)
		if err != nil {
			code = -1
			msg = fmt.Sprintf("not found wxuser by uid<%d>", who.Uid)
			break
		}

		request.UnifiedOrderRequest.OpenId = wxuser.OpenId

		result, paySignResult, err := vc.wxWeappMchPayService.UnifiedorderByAppWho(who, request.UnifiedOrderRequest, request.PayTo)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		resp.UnifiedOrderResponse = result
		resp.PaySignResult = paySignResult
		response["data"] = resp
		break
	}


	response["code"] = code
	response["msg"] = msg
	ctxExt.JSON(200, response)

}


//MicroPay扫码支付
func (vc *WechatPayApiCtrl) MicroPay(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := "success"

	type Request struct {
		*pay.MicroPayRequest
	}

	type Resp struct {
		*pay.MicroPayResponse
	}

	var request Request
	var resp Resp

	for {
		sessionData := common.GetSessionData(&ctxExt)
		who := sessionData.AppTokenWho

		requestByte := ctxExt.PostBody()
		err := xml.Unmarshal(requestByte, &request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		if request.AuthCode == "" {
			code = -1
			msg = "无授权码"
			break
		}

		//先根据auth_code查出付款用户是否有会员卡
		authCodeToOpenIdRequest := paytools.AuthCodeToOpenIdRequest{
			AuthCode:request.AuthCode,
		}
		respAuthCode, err := vc.wxWeappMchPayService.AuthCodeToOpenId(who, &authCodeToOpenIdRequest)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		//之后查询此用户是否有会员卡，这里可以根据会员卡等级批价
		respAuthCode.OpenId = respAuthCode.OpenId

        //再进行扫码支付操作
		result, err := vc.wxWeappMchPayService.MicroPayByAppWho(who, request.MicroPayRequest)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}




		resp.MicroPayResponse = result
		//response["data"] = resp
		break
	}


	response["code"] = code
	response["msg"] = msg
	response["data"] = resp
	ctxExt.JSON(200, response)

}


func (vc *WechatPayApiCtrl) OrderQuery(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := "success"

	type Request struct {
		pay.OrderQueryRequest
	}

	type Resp struct {
		*pay.OrderQueryResponse
	}

	var request Request
	var resp Resp

	for {
		sessionData := common.GetSessionData(&ctxExt)
		who := sessionData.AppTokenWho

		requestByte := ctxExt.PostBody()
		err := xml.Unmarshal(requestByte, &request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		result, err := vc.wxWeappMchPayService.OrderQueryByAppWho(who, request.OrderQueryRequest)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		resp.OrderQueryResponse = result
		//response["data"] = resp
		break
	}


	response["code"] = code
	response["msg"] = msg
	response["data"] = resp
	ctxExt.JSON(200, response)

}

func (vc *WechatPayApiCtrl) CloseOrder(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := "success"

	type Request struct {
		pay.CloseOrderRequest
	}

	type Resp struct {
	}

	var request Request
	var resp Resp

	for {
		sessionData := common.GetSessionData(&ctxExt)
		who := sessionData.AppTokenWho

		requestByte := ctxExt.PostBody()
		err := xml.Unmarshal(requestByte, &request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		err = vc.wxWeappMchPayService.CloseOrderByAppWho(who, request.CloseOrderRequest)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		//resp.GetSignKeyResponse = result
		//response["data"] = resp
		break
	}


	response["code"] = code
	response["msg"] = msg
	response["data"] = resp
	ctxExt.JSON(200, response)

}

func (vc *WechatPayApiCtrl) Refund(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := "success"

	type Request struct {
		pay.RefundRequest
	}

	type Resp struct {
		*pay.RefundResponse
	}

	var request Request
	var resp Resp

	for {
		sessionData := common.GetSessionData(&ctxExt)
		who := sessionData.AppTokenWho

		requestByte := ctxExt.PostBody()
		err := xml.Unmarshal(requestByte, &request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		result, err := vc.wxWeappMchPayService.RefundByAppWho(who, request.RefundRequest)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		resp.RefundResponse = result
		//response["data"] = resp
		break
	}


	response["code"] = code
	response["msg"] = msg
	response["data"] = resp
	ctxExt.JSON(200, response)

}

func (vc *WechatPayApiCtrl) RefundQuery(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := "success"

	type Request struct {
		pay.RefundQueryRequest
	}

	type Resp struct {
		*pay.RefundQueryResponse
	}

	var request Request
	var resp Resp

	for {
		sessionData := common.GetSessionData(&ctxExt)
		who := sessionData.AppTokenWho

		requestByte := ctxExt.PostBody()
		err := xml.Unmarshal(requestByte, &request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		result, err := vc.wxWeappMchPayService.RefundQueryByAppWho(who, request.RefundQueryRequest)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		resp.RefundQueryResponse = result
		//response["data"] = resp
		break
	}


	response["code"] = code
	response["msg"] = msg
	response["data"] = resp
	ctxExt.JSON(200, response)

}

func (vc *WechatPayApiCtrl) Reverse(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := "success"

	type Request struct {
		pay.ReverseRequest
	}

	type Resp struct {
		*pay.ReverseResponse
	}

	var request Request
	var resp Resp

	for {
		sessionData := common.GetSessionData(&ctxExt)
		who := sessionData.AppTokenWho

		requestByte := ctxExt.PostBody()
		err := xml.Unmarshal(requestByte, &request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		result, err := vc.wxWeappMchPayService.ReverseByAppWho(who, request.ReverseRequest)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		resp.ReverseResponse = result
		//response["data"] = resp
		break
	}


	response["code"] = code
	response["msg"] = msg
	response["data"] = resp
	ctxExt.JSON(200, response)

}


func (vc *WechatPayApiCtrl) GetSignKey(ctx *fasthttp.RequestCtx) {
	ctxExt := lego.RequestCtxExtent{ctx}
	response := make(map[string]interface{})
	code := 0
	msg := "success"

	type Request struct {
		sandbox.GetSignKeyRequest
	}

	type Resp struct {
		*sandbox.GetSignKeyResponse
	}

	var request Request
	var resp Resp

	for {
		sessionData := common.GetSessionData(&ctxExt)
		who := sessionData.AppTokenWho

		requestByte := ctxExt.PostBody()
		err := xml.Unmarshal(requestByte, &request)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		result, err := vc.wxWeappMchPayService.GetSignKeyByAppWho(*who, request.GetSignKeyRequest)
		if err != nil {
			code = -1
			msg = err.Error()
			break
		}

		resp.GetSignKeyResponse = result
		//response["data"] = resp
		break
	}


	response["code"] = code
	response["msg"] = msg
	response["data"] = resp
	ctxExt.JSON(200, response)

}

